﻿using sonic.Samples.Infrastructure.ViewModels;
using sonic.Samples.Infrastructure.Services;
using sonic.Samples.Infrastructure.Model;
using System.Collections.Generic;
using Microsoft.Practices.Composite.Events;
using sonic.Samples.Infrastructure.Events;
using System.Windows.Input;
using Microsoft.Practices.Composite.Presentation.Commands;
using Microsoft.Maps.MapControl;
using Modules.AccountMgmt.GeocodeSvc;
using System;
using System.ServiceModel;

namespace Modules.AccountMgmt
{
    public class AccountViewModel : ViewModelBase
    {
        private IAccountService accountService;
        private IEventAggregator eventAggregator;
        private ICommand findCoordinatesCommand;
        public ICommand FindCoordinatesCommand {
            get {
                if (findCoordinatesCommand == null)
                    findCoordinatesCommand = new DelegateCommand<object>(FindCoordinatesExecute, FindCoordinatesCanExecute);
                return findCoordinatesCommand;
            }
        }


        public AccountViewModel(IAccountService accountService, IEventAggregator eventAggregator)
            : base() {
            this.DisplayName = "Account Management";
            this.accountService = accountService;
            this.eventAggregator = eventAggregator;
        }

        public Account CurrentAccount {
            get { return this.accountService.GetCurrent(); }
            set {
                if (value == null) return;
                this.accountService.SetCurrent(value.LastName);
                base.NotifyPropertyChanged("CurrentAccount");
                this.eventAggregator.GetEvent<CurrentAccountEvent>().Publish(value);
            }
        }

        public IEnumerable<Account> Accounts {
            get { return this.accountService.GetAll(); }
        }

        private void FindCoordinatesExecute(object o) {
            GeocodeRequest geocodeRequest = new GeocodeRequest();

            // Set the credentials using a valid Bing Maps key
            geocodeRequest.Credentials = new Credentials();
            geocodeRequest.Credentials.ApplicationId = "AhSKkPRsDPOSzUfkpWCC-HZsrYLj9c5hFTH2lrHkKjierNn2zCdvUWMC4NeZ639m";

            // Set the full address query
            geocodeRequest.Query = ((Account)o).Address;

            // Set the options to only return high confidence results 
            System.Collections.ObjectModel.ObservableCollection<FilterBase> filters = new System.Collections.ObjectModel.ObservableCollection<FilterBase>();
            ConfidenceFilter filter = new ConfidenceFilter();
            filter.MinimumConfidence = GeocodeSvc.Confidence.High;
            filters.Add(filter);

            GeocodeOptions geocodeOptions = new GeocodeOptions();
            geocodeOptions.Filters = filters;

            geocodeRequest.Options = geocodeOptions;

            if (geocodeRequest.Query != "") {
                GeocodeSvcClient geocodeService = new GeocodeSvcClient(new BasicHttpBinding(BasicHttpSecurityMode.Transport), new EndpointAddress("https://dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc"));
                geocodeService.GeocodeCompleted += new EventHandler<GeocodeCompletedEventArgs>(geocodeService_GeocodeCompleted);
                geocodeService.GeocodeAsync(geocodeRequest);
            }
        }

        void geocodeService_GeocodeCompleted(object sender, GeocodeCompletedEventArgs e) {
            // The result is a GeocodeResponse object
            GeocodeResponse geocodeResponse = e.Result;
            if (geocodeResponse.Results.Count > 0) {
                CurrentAccount.CurrentLocation.Latitude = geocodeResponse.Results[0].Locations[0].Latitude;
                CurrentAccount.CurrentLocation.Longitude = geocodeResponse.Results[0].Locations[0].Longitude;
            } else {
                CurrentAccount.CurrentLocation = new Coordinates();
            }
            base.NotifyPropertyChanged("CurrentAccount");
            this.eventAggregator.GetEvent<CurrentAccountEvent>().Publish(CurrentAccount);
        }
        private bool FindCoordinatesCanExecute(object o) {
            return true;
        }
    }
}
